﻿using System;
using System.Collections;
using UnityEngine;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

namespace Gameplay.PVE
{
    public class StreamLodMesh : MonoBehaviour
    {
        public string MeshDataPath;
        public LODGroup lodGroup;
        LOD[] lods;
        bool existLod0 = false;

        public Renderer[] rendererLods0;
        public Renderer[] rendererLods1;
        public Renderer[] rendererLods0_1;
        public MeshFilter[] meshFiltersLods0;
        public MeshFilter[] meshFiltersLods1;
        private MeshData meshData;
        private bool isVisible = false;
        private bool loading = false;

        void Start()
        {
            lods = lodGroup.GetLODs();

            int length = rendererLods0.Length;
            for (int i = 0, len = length; i < len; i++)
            {
                if (meshFiltersLods0[i])
                    meshFiltersLods0[i].sharedMesh = null;
            }

            lods[0].renderers = rendererLods0_1;
            lodGroup.SetLODs(lods);
            StartCoroutine(Loop());
        }

        public void Setup()
        {
            lodGroup = GetComponent<LODGroup>();
            lods = lodGroup.GetLODs();
            rendererLods0 = lods[0].renderers;
            rendererLods1 = lods[1].renderers;
            rendererLods0_1 = new Renderer[rendererLods0.Length + rendererLods1.Length];
            rendererLods0.CopyTo(rendererLods0_1, 0);
            rendererLods1.CopyTo(rendererLods0_1, rendererLods0.Length);
            meshFiltersLods0 = new MeshFilter[rendererLods0.Length];
            meshFiltersLods1 = new MeshFilter[rendererLods1.Length];

            for (int i = 0, len = rendererLods0.Length; i < len; i++)
            {
                var renderer1 = rendererLods0[i];
                if (renderer1)
                    meshFiltersLods0[i] = renderer1.GetComponent<MeshFilter>();
            }
            for (int i = 0, len = rendererLods1.Length; i < len; i++)
            {
                var renderer1 = rendererLods1[i];
                if (renderer1)
                    meshFiltersLods1[i] = renderer1.GetComponent<MeshFilter>();
            }

            int length = rendererLods0.Length;
            for (int i = 0, len = length; i < len; i++)
            {
                if (meshFiltersLods0[i])
                    meshFiltersLods0[i].sharedMesh = null;
            }
        }
        
        IEnumerator Loop()
        {
            float stepTime = 1f;
            var waitForSeconds = new WaitForSeconds(stepTime);

            while (true)
            {
                yield return waitForSeconds;
                //if (Camera.current == null)
                //{
                //    yield return 0;
                //    continue;
                //}

                //float dis = Vector3.Distance(Camera.current.transform.position, transform.position);
                //stepTime = Mathf.Clamp(dis * 0.01f, 0.05f, 10);


                CheckVisible();

                if (loading || !isVisible)
                {
                    // 还在加载中，不要改LOD
                    // 摄像机没有拍到的时候，不要改LOD
                }
                else
                {
                    if (rendererLods0[0].isVisible)
                    {
                        if (!existLod0)
                        {
                            LoadLod0();
                        }
                    }
                    else
                    {
                        if (existLod0)
                        {
                            UnloadLod0();
                        }
                    }
                }
            }
        }
        
        private void UnloadLod0()
        {
            existLod0 = false;
            for (int i = 0, len = meshFiltersLods0.Length; i < len; i++)
                meshFiltersLods0[i].sharedMesh = null;

            if (meshData)
                UMTResource.UnloadAssetImmediately(meshData);

            lods[0].renderers = rendererLods0_1;
            lodGroup.SetLODs(lods);
        }

        private void LoadLod0()
        {
            loading = true;
            UMTResource.LoadAssetRapid(MeshDataPath, (assetName, asset, duration, data) =>
            {
                if (gameObject)
                {
                    loading = false;
                    meshData = asset as MeshData;
                    var meshes = meshData.lodMeshes;

                    int length = Mathf.Min(meshFiltersLods0.Length, meshes.Length);
                    for (int i = 0; i < length; i++)
                    {
                        if (meshFiltersLods0[i])
                            meshFiltersLods0[i].sharedMesh = meshes[i];
                    }

                    lods[0].renderers = rendererLods0;
                    lodGroup.SetLODs(lods);
                    existLod0 = true;
                }
                else
                {
                    UMTResource.UnloadAssetImmediately(asset);
                }
            });
        }

        private void CheckVisible()
        {
            isVisible = rendererLods0[0].isVisible || rendererLods1[0].isVisible;
        }

        void OnDestroy()
        {
            if (meshData)
            {
                UMTResource.UnloadAssetImmediately(meshData);
                meshData = null;
            }
        }
    }
}
